package com.epoint.java8;

import org.junit.Test;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * 4大核心函数式接口
 *
 * 就是java提供了 你再也不用自己去定义一个函数式接口了
 */
public class FunctionDemo {

    /**
     * 1.消费型接口  Consumer<T> 有参数<T> 无返回值
     */
    @Test
    public void test1(){
        consumerTest(500D, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println(aDouble);
            }
        });

        System.out.println("------------------------------------------");

        consumerTest(600D, money -> System.out.println(money));
    }

    public void consumerTest(Double money, Consumer<Double> consumer){
        consumer.accept(money);
    }

    /**
     * 2.供给型接口 Supplier<T> 无参数 有返回值<T>
     */
    @Test
    public void test2(){
        System.out.println(testSupplier(new Supplier<Double>() {
            @Override
            public Double get() {
                return 5000D;
            }
        }));

        System.out.println("------------------------------------------");

        System.out.println(testSupplier( () -> 666D ));
    }

    public Double testSupplier(Supplier<Double> supplier){
        return supplier.get();
    }

    /**
     * 3.函数型接口 Function<T,R> 有参数<T> 有返回值<R>
     */
    @Test
    public void test3(){
        System.out.println(testFunction(500D, new Function<Double, String>() {
            @Override
            public String apply(Double aDouble) {
                return "我今天消费了" + aDouble + "块钱";
            }
        }));

        System.out.println("-----------------------------------------");

        System.out.println(testFunction(666D, money -> "今天我吃饭，吃了"+ money +"块钱"));
    }

    public String testFunction(Double money, Function<Double, String> function){
        return function.apply(money);
    }

    /**
     * 4.断定型接口  Predicate<T>
     */
    @Test
    public void test4(){
        System.out.println(testPredicate(500D, new Predicate<Double>() {
            @Override
            public boolean test(Double aDouble) {
                return aDouble > 666D;
            }
        }));

        System.out.println("---------------------------------");

        System.out.println(testPredicate(1000D, money -> money > 666D));

        List<String> list = new ArrayList<>();
        list.add("jkh");
        list.add("wxy");

        List<String> list2 = new ArrayList<>();
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                if(s.contains("k")){
                    list2.add(s);
                }
            }
        });
        System.out.println(list2);

        System.out.println("---------------------------------");

        List<String> list3 = new ArrayList<>();
        list.forEach(name -> {
            if(name.contains("j")){
                list3.add(name);
            }
        });
        System.out.println(list3);
    }

    public boolean testPredicate(Double d1, Predicate<Double> predicate){
        return predicate.test(d1);
    }

}
